//
//  GameScene.m
//  Cars
//
//  Created by  Stefan Nestorov on 10/11/14.
//  Copyright (c) 2014 Nestorov Engineering. All rights reserved.
//

#import "GameScene.h"
#import "SKTUtils.h"

static const float BG_POINTS_PER_SEC = 200;
static const float SPAWN_TIME = 0.3;

@implementation GameScene
{
    SKNode *_bgLayer;
    SKNode *_objectLayer;
    SKNode *_hudLayer;
    NSTimeInterval _lastUpdateTime;
    NSTimeInterval _dt;
    SKSpriteNode *_player;
    BOOL _shouldMovePlayer;
    NSInteger _score;
    SKLabelNode *_scoreLabel;
    SKLabelNode *_gameOverLabel;
}

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */
    
    [self runAction:[SKAction repeatActionForever: [SKAction sequence:@[[SKAction performSelector:@selector(spawnEnemy) onTarget:self], [SKAction waitForDuration:SPAWN_TIME]]]]];
}


-(instancetype)initWithSize:(CGSize)size
{
    
    if ( self = [super initWithSize:size] ) {
        
        [self initializeBackground];
        [self initializePhysics];
        [self initializePlayer];
        
        _score = 0;
        _hudLayer = [SKNode node];
        _hudLayer.zPosition = _player.zPosition + 1;
        [self addChild:_hudLayer];
        [self initializeHUDLayer];
        
        _objectLayer = [SKNode node];
        [self addChild:_objectLayer];
        
    }
    
    return self;
}


-(void)initializePhysics
{
    
    self.physicsWorld.contactDelegate = self;
    self.physicsWorld.gravity = CGVectorMake(0, 0);
    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
    self.physicsBody.categoryBitMask = PhysicsCategoryEdge;
    self.physicsBody.collisionBitMask = PhysicsCategoryPlayer;
    
}


-(void)initializePlayer
{
    
    _player = [SKSpriteNode spriteNodeWithImageNamed:@"auto"];
    _player.position = CGPointMake(self.size.width/2, 60);
    _player.name = @"player";
    CGSize newSize =  CGSizeMake(_player.size.width-10, _player.size.height-5);
    _player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:newSize];
    _player.physicsBody.categoryBitMask = PhysicsCategoryPlayer;
    _player.physicsBody.contactTestBitMask = PhysicsCategoryObstacle;
    _player.physicsBody.collisionBitMask = PhysicsCategoryEdge;
    _player.physicsBody.affectedByGravity = NO;
    _player.zPosition = 10;
    
    [self addChild:_player];
    
}


-(void)initializeBackground
{
    
    _bgLayer = [SKNode node];
    [self addChild:_bgLayer];
    
    for (int i = 0; i < 2; i++) {
        SKSpriteNode * bg = [[SKSpriteNode alloc] initWithImageNamed:@"bg"];
        bg.anchorPoint = CGPointZero;
        bg.position = CGPointMake(0, i * bg.size.height);
        bg.name = @"bg";
        [_bgLayer addChild:bg];
    }
    
}


-(void)initializeHUDLayer
{
    
    _scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"AvenirNext-Regular"];
    _scoreLabel.text = @"0";
    _scoreLabel.fontSize = 30.0;
    _scoreLabel.fontColor = [SKColor blackColor];
    _scoreLabel.alpha = 1;
    _scoreLabel.position = CGPointMake(self.frame.size.width/2, self.frame.size.height - 30);
    _scoreLabel.hidden = NO;
    [_hudLayer addChild:_scoreLabel];

}


- (void)spawnEnemy
{
    
    SKSpriteNode *enemy = [SKSpriteNode spriteNodeWithImageNamed:@"Obstacle"];
    enemy.name = @"obstacle";
    CGSize newSize =  CGSizeMake(enemy.size.width-10, enemy.size.height-5);
    enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:newSize];
    enemy.physicsBody.categoryBitMask = PhysicsCategoryObstacle;
    enemy.physicsBody.contactTestBitMask = 0;
    enemy.physicsBody.collisionBitMask = 0;
    enemy.physicsBody.affectedByGravity = NO;
    enemy.zPosition = 9;
    
    CGPoint enemyScenePos =
    CGPointMake( RandomFloatRange(enemy.size.width/2, self.size.width-enemy.size.width/2), self.size.height + enemy.size.height/2);
    enemy.position = enemyScenePos;
    [self addChild:enemy];
    
    CGPoint enemyTargetPosition = CGPointMake(enemy.position.x, -enemy.size.height/2);
    
    SKAction *actionMove = [SKAction moveToY:enemyTargetPosition.y duration:2.0];
    SKAction *actionRemove = [SKAction removeFromParent];
    
    __weak GameScene *weakSelf = self;
    SKAction *increeseScoreAction = [SKAction runBlock:^{
        [weakSelf increaseScore];
    }];
    [enemy runAction: [SKAction sequence:@[actionMove, increeseScoreAction, actionRemove]]];
    
}


-(void)increaseScore
{
    
    _score ++;
    _scoreLabel.text = [NSString stringWithFormat:@"%d",_score];
    
}


#pragma mark - Update
-(void)update:(CFTimeInterval)currentTime
{
    /* Called before each frame is rendered */
    
    if ( _lastUpdateTime ) {
        _dt = currentTime - _lastUpdateTime;
    } else {
        _dt = 0;
    }
    _lastUpdateTime = currentTime;
    
    [self moveBackground];
    
}


- (void)moveBackground
{
    
    CGPoint bgVelocity = CGPointMake(0, -BG_POINTS_PER_SEC);
    CGPoint amtToMove = CGPointMultiplyScalar(bgVelocity, _dt);
    _bgLayer.position = CGPointAdd(_bgLayer.position, amtToMove);
    
    [_bgLayer enumerateChildNodesWithName:@"bg" usingBlock: ^(SKNode *node, BOOL *stop) {
        SKSpriteNode *bg = (SKSpriteNode *) node;
        CGPoint bgScreenPos = [_bgLayer convertPoint:bg.position toNode:self];
        if ( bgScreenPos.y <= -bg.size.height ) {
            bg.position = CGPointMake(bg.position.x, bg.position.y + bg.size.height*2);
        }
    }];
    
}


#pragma mark - Touch Events
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    /* Called when a touch begins */
    
    if ( self.paused == YES ) {
        self.paused = NO;
        _gameOverLabel.hidden = YES;
        _score = 0;
        _scoreLabel.text = @"0";
    }
    
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    
    // if Tapped the Player
    if ( [_player containsPoint:location] ) {
        _shouldMovePlayer = YES;
    }
    
}


-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    
    if ( [_player containsPoint:location] && self.paused == NO ) {
        _shouldMovePlayer = YES;
    }
    
    if ( _shouldMovePlayer == YES ) {
        _player.position = CGPointMake(location.x, _player.position.y);
    }
    
}


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    _shouldMovePlayer = NO;
    
}


-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    _shouldMovePlayer = NO;
    
}


#pragma mark - Physics Delegate Method
- (void)didBeginContact:(SKPhysicsContact *)contact
{
    
    uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);
    
    // Obstacle hit Player
    if ( collision == (PhysicsCategoryPlayer | PhysicsCategoryObstacle) ) {
        
        _gameOverLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
        _gameOverLabel.text = @"Game Over";
        _gameOverLabel.fontSize = 40.0;
        _gameOverLabel.fontColor = [SKColor redColor];
        _gameOverLabel.alpha = 1;
        _gameOverLabel.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
        [_hudLayer addChild:_gameOverLabel];
        
        _shouldMovePlayer = NO;
        self.paused = YES;
    }
    
}


@end
